/**
 * Copyright (c) 2007, Blue Hole Software. All rights reserved.
 * Code licensed under the Apache 2.0 License:
 * http://www.apache.org/licenses/
 */
package org.bhf.i18n;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * Collection of Messages.
 */
public class Messages implements Serializable
{
    private static final long serialVersionUID = 3955014636742385274L;

    private static final List<Message> EMPTY_LIST = new ArrayList<Message>(0);

    private final Map<String, List<Message>> messages = new HashMap<String, List<Message>>(); // property (String) to Messages (List of Message)

    /**
     * Merge in additional messages.
     * @param merge Messages to merge.
     */
    public void                         merge( final Messages merge )
    {
        for( final List<Message> list : merge.messages.values() )
            for( final Message message : list )
                addMessage(message);
    }

    /**
     * Merge in additional messages and prepend the given topic prefix.
     * @param merge Messages to merge.
     * @param topicPrefix This prefix will be prepend to the topic of all
     *      merged messages.
     */
    public void                         merge( final Messages merge, final String topicPrefix )
    {
        for( final List<Message> list : merge.messages.values() )
            for( final Message message : list )
                addMessage(message.prependToTopic(topicPrefix));
    }

    /**
     * Return <code>true</code> if this messages is empty.
     * @return <code>true</code> if this messages is empty.
     */
    public boolean                      isEmpty()
    {
        return messages.isEmpty();
    }

    /**
     * Add a message, such as an error or informational message.
     * @param message Must not be <code>null</code>.
     */
    public void                         addMessage( final Message message )
    {
        List<Message> list = messages.get( message.getTopic() );
        if( list == null )
        {
            list = new LinkedList<Message>();
            messages.put( message.getTopic(), list );
        }
        list.add( message );
    }

    /**
     * Return a <code>Map</code> of topic (String) to <code>List</code> of <code>Message</code>s. Must be
     * reated as read-only and not modified.
     * @return All messages - will not be <code>null</code>.
     */
    public Map<String,List<Message>>    getMessages()
    {
        return messages;
    }

    /**
     * Return a flat list of all <code>Message</code>s.
     * @return A flat list of all <code>Message</code>s.
     */
    public List<Message>                getFlatMessages()
    {
        final List<Message> l = new ArrayList<Message>( 32 );
        for( List<Message> lm : messages.values() )
            l.addAll( lm );
        return l;
    }

    /**
     * Return all messages queued for the given topic. The list should be treated
     * as read-only and not modified.
     *
     * @param topic Topic
     * @return May be empty, but not <code>null</code>.
     */
    public List<Message>                getMessagesForTopic( final String topic )
    {
        final List<Message> list = messages.get( topic );
        return list != null ? list : EMPTY_LIST;
    }
}